/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package middlewareWeb;
import java.net.*;
import java.io.*;
import java.util.*;
/**
 *
 * @author myusy
 */
public class WorkerThreadEsegui1 implements Runnable{

    protected TQueueManager queueManager;
    protected Worker1 worker;
    /**
     * Metodo costruttore
     */
    public WorkerThreadEsegui1(Worker1 worker,TQueueManager queueManager){
        this.queueManager = queueManager;
        this.worker = worker;
    }

    public synchronized void run(){

        TaskDescriptor task = queueManager.dequeue();
        String a= queueManager.toXML();
         /* Scrittura Log */
                LoggerMW logger= new LoggerMW();
                logger.creaLog(worker.getId(),worker.IncrementaClock(),
                        worker.IncrementaSequenzaOperazione().toString(),
                        queueManager.getTQueue().size(),
                        worker.getTaskInseriti().toString(),
                        a,"Dequeue effettuata");

                        worker.getProwyRM().getBufferProxy().enqueue(new InfoRM(worker.getId(),"dequeue",task,worker.getWorkerAddress()),worker.getProwyRM().getClocks());

        
        if (task != null){
            
            System.out.println("******************************************** TASK ESTRATTO DALLA CODA");

            try
            {
                //FileOutputStream fos = new FileOutputStream("/home/myusy/Risorsa"+task.getID()+".java");
                DatagramSocket socket = new DatagramSocket();
                ByteArrayOutputStream bout = new ByteArrayOutputStream();

                byte[] datagramMessage = new byte[512];

                String[] addrIP = "127.0.0.1".split("\\.");
                byte[] byteIP = new byte[addrIP.length];
                for(int i = 0;i<addrIP.length;i++)
                   byteIP[i] = Byte.decode(addrIP[i]);

                DatagramPacket datPacket = new DatagramPacket(datagramMessage,datagramMessage.length,InetAddress.getByName("LocalHost"),6000);

                ObjectOutputStream dout = new ObjectOutputStream(bout);

                dout.writeObject(task.getLink());
                dout.flush();
                datagramMessage = bout.toByteArray();
                datPacket.setData(datagramMessage);
                datPacket.setLength(datagramMessage.length);
                socket.send(datPacket);
                bout.reset();

                System.out.println("STO INVIANDO AL MANAGER: "+task.getLink());

                HashMap ReceivedFrag = new HashMap();
                //Vector<UDPReliableData> ReceivedFrag = new Vector<UDPReliableData>();


                int number = 0;
                while(number != -1){

                    byte[] buffer = new byte[1024];
                    DatagramPacket packetIn = new DatagramPacket(buffer,buffer.length);
                    socket.receive(packetIn);

                    System.out.println("Ricevo il pacchetto da " + packetIn.getAddress() + " " + packetIn.getPort());
                    ByteArrayInputStream bin = new ByteArrayInputStream(packetIn.getData());

                    ObjectInputStream oin = new ObjectInputStream(bin);

                    UDPReliableData fragRead = (UDPReliableData)oin.readObject();
                    String s = new String(fragRead.getBuffer(),0,fragRead.getCount());
                    System.out.println("Frammento numero " + fragRead.getSequenceNumber() + " : "+fragRead.getCount());
                    //fos.write(fragRead.getBuffer(),0,fragRead.getCount());
                    oin.close();

                    if ((number = fragRead.getSequenceNumber()) != -1) {
                        System.out.println("Numero sequenza ok " + number);
                        if (!ReceivedFrag.containsKey(number)) {
                            System.out.println("Numero non presente");
                            //CRC32 check = new CRC32();
                            //check.update(fragRead.getBuffer());
                            //long checksum = check.getValue();

                            if (true) {//checksum == fragRead.getChecksum()) {
                                System.out.println("CRC corretta");
                                ReceivedFrag.put(number, fragRead);


                                byte[] bufferAck = new byte[1024];
                                DatagramPacket ackPacket = new DatagramPacket(bufferAck,bufferAck.length,packetIn.getAddress(),packetIn.getPort());
                                ByteArrayOutputStream boutAck = new ByteArrayOutputStream();
                                DataOutputStream doutAck = new DataOutputStream(boutAck);
                                doutAck.writeInt(number);
                                bufferAck = boutAck.toByteArray();
                                ackPacket.setData(bufferAck);
                                ackPacket.setLength(bufferAck.length);
                                socket.send(ackPacket);
                                boutAck.reset();
                                System.out.println("Ack mandato a " + packetIn.getAddress() + " " + packetIn.getPort());
                            }
                        }
                    }
                }

                String link = "/home/myusy/Risorsa"+task.getID()+".jpg";
                FileOutputStream fos = new FileOutputStream(link);
                task.setLink(link);
                //int offset = 0;
                for(int p=1;p<=ReceivedFrag.size();p++)
                {
                    UDPReliableData temp = (UDPReliableData)ReceivedFrag.get(p);
                    fos.write(temp.getBuffer(),0,temp.getCount());
                    //offset+=temp.getCount();
                    System.out.println("Frammento numero " + p + " : "+ temp.getBuffer());
                }
                fos.close();

                }catch(Exception ex){
                        System.out.println("Eccezione WorkerThreadEsegui: " + ex.getMessage());
                }


            worker.exec(task);
        }
    }


}
